package net.mikoo.seals.manage.web.controller;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import net.mikoo.seals.biz.manager.SmsManager;
import net.mikoo.seals.biz.service.CompanyService;
import net.mikoo.seals.biz.service.PartyServices;
import net.mikoo.seals.biz.service.PersonServices;
import net.mikoo.seals.biz.service.StatisticsServices;
import net.mikoo.seals.biz.service.UserLoginServices;
import net.mikoo.seals.biz.service.VerifyService;
import net.mikoo.seals.common.WebContext;
import net.mikoo.seals.common.enums.MobileStatusEnum;
import net.mikoo.seals.common.enums.PartyTypeEnum;
import net.mikoo.seals.common.enums.StaffStatusEnum;
import net.mikoo.seals.common.enums.VerifyStatusEnum;
import net.mikoo.seals.common.exception.AccountDisabledException;
import net.mikoo.seals.common.exception.AccountExpiryException;
import net.mikoo.seals.common.exception.AccountFreezedException;
import net.mikoo.seals.common.exception.AccountNotFindException;
import net.mikoo.seals.common.exception.LoginException;
import net.mikoo.seals.common.exception.ParametersException;
import net.mikoo.seals.common.exception.PasswordErrorException;
import net.mikoo.seals.common.exception.SendSmsException;
import net.mikoo.seals.manage.web.common.BaseController;
import net.mikoo.seals.model.ApplyVerify;
import net.mikoo.seals.model.ApplyVerifyQuery;
import net.mikoo.seals.model.Company;
import net.mikoo.seals.model.CompanyQuery;
import net.mikoo.seals.model.Party;
import net.mikoo.seals.model.PartyQuery;
import net.mikoo.seals.model.Staff;
import net.mikoo.seals.model.UserLogin;
import net.mikoo.seals.utils.DateUtil;
import net.mikoo.seals.utils.StringUtil;
import net.mikoo.seals.utils.ValidatorUtil;
import net.sf.json.JSONObject;


@Controller
public class MemberController extends BaseController{
	

	Logger logger = Logger.getLogger(MemberController.class);

	@Autowired
	private UserLoginServices userLoginServices;
	
	@Autowired
	private PartyServices partyServices;
	
	@Autowired
	private PersonServices personServices;
	
	@Autowired
	private StatisticsServices statisticsServices;
	
	@Autowired
	private VerifyService verifyService;
	
	
	@Autowired
	private CompanyService companyService;
	
	@Autowired
	private SmsManager smsManager;
	
	
	@Autowired
	private RedisTemplate<String, String> redisTemplate;
	

	/**
	 * 登录界面
	 * 
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/login")
	public String login(HttpServletRequest request, Model model) {
		
	/*	try{
			getLoginUser(request);
			//model.addAttribute("userLogin", userLogin);
		}catch(UserNotLoginException e){
			return this.resultView(ADMIN_VIEW,"login");
		}*/
		//String basePath = (String) request.getAttribute("basePath");
		//return redirect(basePath+"member/main.htm",model);
		
		return "login";
	}
	
	
	@RequestMapping("/firstLogin")
	public String firstLogin(HttpServletRequest request, Model model) {
		
		
		return "firstLogin";
	}
	
	
	
	@RequestMapping("/firstLogin/sendsms")
	@ResponseBody
	public Map<String, Object> firstLoginSendsms(String mobile,String authCode, HttpServletRequest request) {
		
		
		try {
			
			
			UserLogin userLogin = userLoginServices.loadByPrimaryKey(mobile);
			if(userLogin ==null) {
				return  result(ERROR, "非法操作");
			}
			
			String SMS_SEND_DATETIME = "SMS_SEND_DATETIME";
			
			
			String sendTime = redisTemplate.opsForValue().get(SMS_SEND_DATETIME.concat(mobile));
			if(StringUtils.isNotBlank(sendTime)) {
				Date sendDatetime = DateUtil.stringToDate(sendTime.toString(), "yyyy-MM-dd HH:mm:ss");
				Date currentDatetime = DateUtil.getCurretDate();
				sendDatetime = DateUtil.addMinute(sendDatetime, 1);
				if (DateUtil.compare(sendDatetime, currentDatetime) > 0) {
					throw new ParametersException("您操作太频繁，请稍微再试");
				}
				
			}
			
			//生成短信随机码
			String smscode = StringUtil.getRandNum(6);
			System.out.println(smscode);
			JSONObject data = new JSONObject();
			data.put("code", smscode);
			
			
			
	
			try {
				smsManager.sendSms(mobile, "SMS_147435007", data.toString());
				
				redisTemplate.opsForValue().set(SMS_SEND_DATETIME.concat(mobile),DateUtil.formate(new Date(), "yyyy-MM-dd HH:mm:ss"));
				redisTemplate.opsForValue().set("sms_send_code_".concat(mobile), smscode);
			}catch (SendSmsException e) {
				throw new ParametersException("短信发送失败");
			}
		
			return result(SUCCESS,"ok");
		
		} catch (ParametersException e) {
			logger.error("",e);
			return result(ERROR, e.getMessage());
		} catch (Exception e) {
			logger.error("",e);
			return result(ERROR, MSG_SYSTEM_ERROR);
		}
		
	}
	
	
	@RequestMapping("/firstLogin/change")
	@ResponseBody
	public Map<String, Object> firstLoginChange(String mobile,String authCode,String newPassword, HttpServletRequest request) {
		
		if(StringUtils.isBlank(authCode)) {
			return  result(ERROR, "请输入验证码");
		}
		
		if(StringUtils.isBlank(newPassword)) {
			return  result(ERROR, "请输入新密码");
		}
		
		
		String smscode = redisTemplate.opsForValue().get("sms_send_code_".concat(mobile));
		if(StringUtils.isBlank(smscode) || !authCode.equals(smscode)) {
			return  result(ERROR, "手机验证码输入有误");
		}
		
		
		try {
			userLoginServices.changePasswordByForget(mobile, newPassword);
		}catch (Exception e) {
			logger.error("",e);
			return result(ERROR,"修改失败");
		}
		
		return result(SUCCESS,"OK");
		
	}

	/**
	 * 登录
	 * 
	 * @param username
	 * @param password
	 * @param code
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/signin", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Object> signin(Model model, HttpServletRequest request)  {
		
		
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		String authcode = request.getParameter("authcode");

		try {

			HttpSession session = request.getSession();
			String kaptchaCode = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
			if (StringUtils.isEmpty(authcode) || StringUtils.isEmpty(kaptchaCode) || !kaptchaCode.equals(authcode)) {
				logger.error("验证码出错！");
				return result(ERROR,"验证码错误");
			}

			Party party = userLoginServices.authLogin(username, password, PartyTypeEnum.OPERATOR.code());

			retainSession(party, request, WebContext.ADMIN_LOGIN_SESSION_KEY);
			
//			Map<String,Object> data = new HashMap<>();
//			data.put("userLoginId", party.getPerson().getMobile());
//			data.put("status", party.getPerson().getMobileStatus());
//			data.put("status", party.getPartyId());
			
			return result(SUCCESS,"登陆成功");
			// return redirectTips("/admin/login.htm", "用户名或密码错误", model);

		} catch (ParametersException | AccountNotFindException | AccountDisabledException| AccountFreezedException |AccountExpiryException| PasswordErrorException e) {
			logger.error("", e);
			return result(ERROR,e.getMessage());
		} catch (Exception e) {
			logger.error("登录系统出错！", e);
			return result(ERROR,"系统出错，请联系管理员");
		}
	}
	
	
	@RequestMapping("/check")
	public String check(HttpServletRequest request, Model model) {
		
		Party party = getParty(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
		if(party == null) {
			return redirect("/login.htm");
		}
		model.addAttribute("party", party);
		
		return "check";
	}
	
	
	@RequestMapping("/company")
	public String company(HttpServletRequest request, Model model) {
		
		Party party = getParty(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
		if(party == null) {
			return redirect("/login.htm");
		}
		
		List<Company> companys = companyService.getListByPartyId(party.getPartyId());
		model.addAttribute("companys", companys);
		
		return "company";
	}
	
	@RequestMapping("/company/selected")
	@ResponseBody
	public Map<String,Object> companySelected(CompanyQuery query,HttpServletRequest request, Model model) {
		
		
		
		Party party = getParty(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
		if(party == null) {
			return result("-001", "未登陆");
		}
		
		query.setPartyId(party.getPartyId());
		Company company = companyService.getSelectedByQuery(query);
		if(company == null) {
			return result("-001", "未找到公司");
		}
		
		Staff staff = company.getStaff();
		if(staff == null) {
			return result("-001", "员工信息不存在");
		}
		if(!staff.getStaffStatus().equals(StaffStatusEnum.NORMAL.code())) {
			return result("-002", "账户已冻结");
		}
		
		HttpSession session = request.getSession();
		session.setAttribute(WebContext.ADMIN_COMPANY_KEY,company);
		
		return result(SUCCESS, "ok");
	}
	
	
	@RequestMapping("/check/submit")
	@ResponseBody
	public Map<String,Object> checkSubmit(String smscode,HttpServletRequest request, Model model) {
		
		try {

			
			Party party = getParty(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
			if(party == null) {
				throw new LoginException("账户未登陆");
			}
			
			String cachesmsCode = redisTemplate.opsForValue().get("sms_send_code_".concat(party.getUserLoginId()));
			if(!smscode.equals(cachesmsCode)) {
				throw new ParametersException("短信验证码输入有误");
			}
			
			
			personServices.modifyMobileStatus(party.getPartyId(), MobileStatusEnum.CERTIFIED.code());

			
			party = partyServices.loadByPrimaryKey(party.getPartyId());
			retainSession(party, request, WebContext.ADMIN_LOGIN_SESSION_KEY);
			
			return result(SUCCESS,"登陆成功");
			// return redirectTips("/admin/login.htm", "用户名或密码错误", model);

		} catch (ParametersException | AccountNotFindException | AccountDisabledException| AccountFreezedException |AccountExpiryException| PasswordErrorException e) {
			logger.error("", e);
			return result(ERROR,e.getMessage());
		} catch (Exception e) {
			logger.error("登录系统出错！", e);
			return result(ERROR,"系统出错，请联系管理员");
		}
	}

	/**
	 * 登出
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/logout")
	public String logout(HttpServletRequest request, Model model) {
		
		removeSession(request,WebContext.ADMIN_LOGIN_SESSION_KEY);
		removeSession(request,WebContext.ADMIN_COMPANY_KEY);
		//String basePath = (String) request.getAttribute("basePath");
		return redirect("/login.htm");
	}
	/**
	 * 忘记密码
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/forgetPwd")
	public String forgetPwd(HttpServletRequest request, Model model) {
		
		return  "forgetPwd";
	}
	
	@RequestMapping("/forgetPwd/check")
	@ResponseBody
	public Map<String, Object> forgetPwdCheck(String mobile,String checkCode, HttpServletRequest request) {
		
		if(StringUtils.isBlank(mobile)) {
			return  result(ERROR, "请输入手机号码");
		}
		
		if (!ValidatorUtil.isMobile(mobile)) {
			throw new ParametersException("手机号码输入有误");
		}
		
		if(StringUtils.isBlank(checkCode)) {
			return  result(ERROR, "请输入校验码");
		}
		
		HttpSession session = request.getSession();
		String kaptchaCode = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		if (StringUtils.isEmpty(checkCode) || StringUtils.isEmpty(kaptchaCode) || !kaptchaCode.equals(checkCode)) {
			logger.error("验证码出错！");
			return result(ERROR,"验证码错误");
		}
		
		UserLogin userLogin = userLoginServices.loadByPrimaryKey(mobile);
		if(userLogin ==null) {
			return  result(ERROR, "手机号码不存在或输入有误");
		}
		
		return result(SUCCESS,"ok",mobile);
	}
	
	
	@RequestMapping("/forgetPwd/sendsms")
	@ResponseBody
	public Map<String, Object> forgetPwdSendsms(String mobile,String checkCode,String authCode, HttpServletRequest request) {
		
		
		try {
		
			
			if(StringUtils.isBlank(mobile) || StringUtils.isBlank(checkCode)) {
				return  result(ERROR, "非法操作");
			}
			
			
			HttpSession session = request.getSession();
			String kaptchaCode = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
			if (StringUtils.isEmpty(checkCode) || StringUtils.isEmpty(kaptchaCode) || !kaptchaCode.equals(checkCode)) {
				logger.error("验证码出错！");
				return result(ERROR,"非法操作");
			}
			
			UserLogin userLogin = userLoginServices.loadByPrimaryKey(mobile);
			if(userLogin ==null) {
				return  result(ERROR, "非法操作");
			}
			
			String SMS_SEND_DATETIME = "SMS_SEND_DATETIME";
			
			
			String sendTime = redisTemplate.opsForValue().get(SMS_SEND_DATETIME.concat(mobile));
			if(StringUtils.isNotBlank(sendTime)) {
				Date sendDatetime = DateUtil.stringToDate(sendTime.toString(), "yyyy-MM-dd HH:mm:ss");
				Date currentDatetime = DateUtil.getCurretDate();
				sendDatetime = DateUtil.addMinute(sendDatetime, 1);
				if (DateUtil.compare(sendDatetime, currentDatetime) > 0) {
					throw new ParametersException("您操作太频繁，请稍微再试");
				}
				
			}
			
			//生成短信随机码
			String smscode = StringUtil.getRandNum(6);
			System.out.println(smscode);
			JSONObject data = new JSONObject();
			data.put("code", smscode);
			
			
			
	
			try {
				smsManager.sendSms(mobile, "SMS_163852927", data.toString());
				
				redisTemplate.opsForValue().set(SMS_SEND_DATETIME.concat(mobile),DateUtil.formate(new Date(), "yyyy-MM-dd HH:mm:ss"));
				redisTemplate.opsForValue().set("sms_send_code_".concat(mobile), smscode);
			}catch (SendSmsException e) {
				throw new ParametersException("短信发送失败");
			}
		
			return result(SUCCESS,"ok");
		
		} catch (ParametersException e) {
			logger.error("",e);
			return result(ERROR, e.getMessage());
		} catch (Exception e) {
			logger.error("",e);
			return result(ERROR, MSG_SYSTEM_ERROR);
		}
		
	}
	
	
	@RequestMapping("/forgetPwd/change")
	@ResponseBody
	public Map<String, Object> forgetPwdChange(String mobile,String checkCode,String authCode,String newPassword,String confirmPassword, HttpServletRequest request) {
		
		if(StringUtils.isBlank(authCode)) {
			return  result(ERROR, "请输入验证码");
		}
		
		if(StringUtils.isBlank(newPassword)) {
			return  result(ERROR, "请输入新密码");
		}
		
		if(StringUtils.isBlank(confirmPassword)) {
			return  result(ERROR, "请输入确认密码");
		}
		
		if(!newPassword.equals(confirmPassword)) {
			return  result(ERROR, "两次密码输入不一致");
		}
		
		
		String smscode = redisTemplate.opsForValue().get("sms_send_code_".concat(mobile));
		if(StringUtils.isBlank(smscode) || !authCode.equals(smscode)) {
			return  result(ERROR, "手机验证码输入有误");
		}
		
		
		if(StringUtils.isBlank(mobile) || StringUtils.isBlank(checkCode)) {
			return  result(ERROR, "非法操作");
		}
		
		
		HttpSession session = request.getSession();
		String kaptchaCode = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);
		if (StringUtils.isEmpty(checkCode) || StringUtils.isEmpty(kaptchaCode) || !kaptchaCode.equals(checkCode)) {
			logger.error("验证码出错！");
			return result(ERROR,"非法操作");
		}
		
		try {
			userLoginServices.changePasswordByForget(mobile, newPassword);
		}catch (Exception e) {
			logger.error("",e);
			return result(ERROR,"修改失败");
		}
		
		return result(SUCCESS,"OK");
		
	}
	
	
	
	
	@RequestMapping("/index")
	public String index(HttpServletRequest request,Model model) {
		UserLogin userLogin = getLoginUser(request,WebContext.ADMIN_LOGIN_SESSION_KEY);
		Long companyId = getCompanyId(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
		Long partyId = getCurrentPartyId(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
		
		model.addAttribute("userLogin", userLogin);
		
		//查询统计数据
		Map<String,Object> datas = statisticsServices.countTotal(companyId, partyId);
		model.addAllAttributes(datas);
		
		//查询待办
		ApplyVerifyQuery query = new ApplyVerifyQuery();
		query.setCompanyId(companyId);
		query.setPartyId(partyId);
		query.setVerifyStatus(VerifyStatusEnum.PENDING.code());
		List<ApplyVerify> verifys =  verifyService.getListByQuery(query);
		model.addAllAttributes(verifys);
		return "index";
	}
	
	
	
	/**
	 * 管理主界面
	 * @param request
	 * @param model
	 * @return
	 */
	@RequestMapping("/main")
	public String main(HttpServletRequest request,Model model) {
		
		UserLogin userLogin = getLoginUser(request,WebContext.ADMIN_LOGIN_SESSION_KEY);
		if(userLogin == null){
			return redirect("/admin/login.htm");
		}
		model.addAttribute("userLogin", userLogin);
		return "main";
	}
	
	
	
	/**
	 * ajax验证登录帐户是否唯一
	 * 
	 * @param userLoginId
	 * @return
	 */
	@RequestMapping("/usernameIsUnique")
	@ResponseBody
	public Map<String, String> usernameIsUnique(String userLoginId, String excludeKey) {
		Map<String, String> res = new HashMap<String, String>();

		Boolean b = partyServices.checkExist(userLoginId, excludeKey, "username");
		if (b) {
			res.put("code", "1");
			return res;
		} else {
			res.put("code", "0");
			return res;
		}
		// res.put("code", "-1");
		// res.put("message", result.getMessage());
		//
		// return res;
	}

	/**
	 * ajax验证邮箱帐户是否唯一
	 * 
	 * @param userLoginId
	 * @return
	 */
	@RequestMapping("/emailIsUnique")
	@ResponseBody
	public Map<String, String> emailIsUnique(String email, String excludeKey) {

		Map<String, String> res = new HashMap<String, String>();

		Boolean b = partyServices.checkExist(email, excludeKey, "email");
		if (b) {
			res.put("code", "1");
			return res;
		} else {
			res.put("code", "0");
			return res;
		}
		//res.put("code", "-1");
		//res.put("message", result.getMessage());

		//return res;

	}
	
	
	
	
	
	
	
	
	@RequestMapping("/party/search")
	@ResponseBody
	public Map<String, Object> search(String searchKey, HttpServletRequest request){
		try {
			
			if(StringUtils.isBlank(searchKey)) {
				throw new ParametersException("搜索关键字不能为空");
			}
			
			Long companyId = getCompanyId(request, WebContext.ADMIN_LOGIN_SESSION_KEY);
			if(companyId == null) {
				throw new IllegalArgumentException("登陆过期");
			}
			PartyQuery query = new PartyQuery();
			query.setSearchKey(searchKey);
			query.setSearchType("nameOrUserLoginId");
			query.setCompanyId(companyId);
			return result(SUCCESS, "查询成功", toPartyInfoList(partyServices.getListByQuery(query)));
		} catch (ParametersException | AccountNotFindException | AccountDisabledException| AccountFreezedException |AccountExpiryException| PasswordErrorException e) {
			logger.error("", e);
			return result(ERROR,e.getMessage());
		} catch (Exception e) {
			logger.error("系统出错！", e);
			return result(ERROR,"系统出错，请联系管理员");
		}
	}
	
	private List<Map<String, Object>> toPartyInfoList(List<Party> partyList){
		if(partyList == null || partyList.isEmpty()) {
			return null;
		}
		
		List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
		for(Party party : partyList) {
			if(party == null || 
					StringUtils.isBlank(party.getUserLoginId()) || 
					party.getPerson() == null) {
				continue;
			}
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("userLoginId", party.getUserLoginId());
			map.put("name", party.getPerson().getName());
			
			result.add(map);
		}
		return result;
	}
}
